#include "fileUtil.hpp"
#include "jsonUtil.hpp"
#include "config.hpp"
#include "dataManager.hpp"
#include "hotManager.hpp"
#include "service.hpp"
#include <thread>
using namespace std;

// g++ svrTest.cpp -o svrTest -lstdc++fs  -L./mylib/lib/ -lbundle -lpthread #bundle使用了线程

//./svrTest ./makefile
void FileUtilTest(const std::string &filePath)
{
	// bash-stat 可查看文件属性信息
	cloudBackup::FileUtil fileUtil(filePath);
	std::cout << fileUtil.FileSize() << std::endl;
	std::cout << fileUtil.LastATime() << std::endl;
	std::cout << fileUtil.LastCTime() << std::endl;
	std::cout << fileUtil.LastMTime() << std::endl;
	std::cout << fileUtil.FileName() << std::endl;

	std::string content;
	fileUtil.GetContent(&content);
	cout << "get content: " << content << endl;

	//./hello.txt不存在自动创建
	cloudBackup::FileUtil fileUtil2("./hello.txt");
	fileUtil2.SetContent(content);
	cout << "set content: " << content << endl;

	cloudBackup::FileUtil fileUtil3(filePath);
	std::string zipFile = filePath + ".lz";
	fileUtil3.Compress(zipFile);
	cloudBackup::FileUtil fileUtil4(zipFile);
	fileUtil4.DeCompress("MyDeCom.txt");

	// 只能创建目录 /a/b/test.txt 会把test.txt也认为是目录
	// fileUtil.CreateDirectory();
	// if (fileUtil.Exists())
	// 	std::cout << "ok" << std::endl;

	// ./svrTest ./testdir
	// ./testdir/a.txt ./testdir/b.txt
	// std::vector<std::string> array;
	// fileUtil.ScanDirectory(&array);
	// for (auto &perFile : array)
	// 	std::cout << perFile << std::endl;

	return;
}

// g++ svrTest.cpp -o svrTest -lstdc++fs  -L./mylib/lib/ -lbundle -lpthread -ljsoncpp
void JsonUtilTest()
{
	const char *name = "小明";
	int age = 19;
	float score[] = {85, 88.5, 99};
	Json::Value root;
	root["姓名"] = name;
	root["年龄"] = age;
	root["成绩"].append(score[0]);
	root["成绩"].append(score[1]);
	root["成绩"].append(score[2]);
	std::string str;
	cloudBackup::JsonUtil::Serialize(root, &str);
	std::cout << str << std::endl;

	Json::Value val;
	cloudBackup::JsonUtil::Deserialize(str, &val);
	std::cout << val["姓名"].asString() << std::endl;
	std::cout << val["年龄"].asInt() << std::endl;
	for (int i = 0; i < val["成绩"].size(); i++)
		std::cout << val["成绩"][i].asFloat() << std::endl;
}

void ConfigTest()
{
	cloudBackup::Config *config = cloudBackup::Config::GetInstance();
	std::cout << config->GetHotTime() << std::endl;
	std::cout << config->GetServerPort() << std::endl;
	std::cout << config->GetServerIp() << std::endl;
	std::cout << config->GetUrlDownloadID() << std::endl;
	std::cout << config->GetZipSuffix() << std::endl;
	std::cout << config->GetZipDir() << std::endl;
	std::cout << config->GetBackupDir() << std::endl;
	std::cout << config->GetBackupAInfoFName() << std::endl;
}

void DataTest(const std::string &filePath)
{
	// 假设命令行参数传来的文件是备份文件 为该文件设置备份信息
	std::cout << "NewBackupAInfo " << std::endl;
	cloudBackup::BackupAInfo info;
	info.NewBackupAInfo(filePath);
	info.showMsg();
	std::cout << std::endl;

	// 将备份文件信息添加到表中 与ReqDownloadPath形成映射
	// dataManager一旦实例化 调用构造 获取存放备份文件属性信息的文件名
	// 把备份文件属性信息从文件加载到内存(hashMap)
	std::cout << "GetOneByReqDownloadPath" << std::endl;
	cloudBackup::DataManager dataManager;
	dataManager.Insert_Table(info);
	cloudBackup::BackupAInfo tmp;
	dataManager.GetOneByReqDownloadPath("/download/makefile", &tmp);
	tmp.showMsg();
	std::cout << std::endl;

	std::cout << "GetAllBackupAInfo " << std::endl;
	std::vector<cloudBackup::BackupAInfo> array;
	dataManager.GetAllBackupAInfo(&array);
	for (auto &a : array)
		a.showMsg();
	std::cout << std::endl;

	std::cout << "info._isZipped = true " << std::endl;
	info._isZipped = true;
	dataManager.Update_Table(info);
	array.clear();
	dataManager.GetAllBackupAInfo(&array);
	for (auto &a : array)
		a.showMsg();
	std::cout << std::endl;

	std::cout << "GetOneByRealPath" << std::endl;
	dataManager.GetOneByFilePath(filePath, &tmp);
	tmp.showMsg();
	std::cout << std::endl;
}

// 声明全局指针对象 如果声明为局部的
// 当出了作用域 生命周期截止 指针对象销毁 堆空间泄露
// cloudBackup::DataManager *_dataManager;
std::shared_ptr<cloudBackup::DataManager> _dataManager;
void HotTest()
{
	cloudBackup::HotManager hot;
	hot.RunHotManager();
}

void ServiceTest()
{
	cloudBackup::Service srv;
	srv.RunServiceModule();
}

void TimeStrTest()
{
	time_t now = time(nullptr);
	char *ctime_str = std::ctime(&now);
	std::string tmp(ctime_str);
	// Sat Aug 17 10:57:21 2024
	std::cout << tmp << std::endl;
	return;
}

int main(int argc, char *argv[])
{
	// FileUtilTest(argv[1]);
	// JsonUtilTest();
	// ConfigTest();
	// DataTest(argv[1]);
	// TimeStrTest();

	//_dataManager 的定义在程序其他部分尝试访问它之前就已经完成
	// _dataManager = new cloudBackup::DataManager();
	std::shared_ptr<cloudBackup::DataManager> ptr(new cloudBackup::DataManager());
	_dataManager = ptr;
	// HotTest();
	// ServiceTest();

	// 服务端启动
	std::thread thread_hotManager(HotTest);
	std::thread thread_serviceModule(ServiceTest);
	thread_hotManager.join();
	thread_serviceModule.join();

	//_dataManager是否需要delete：不需要
	// hotTest/serviceTest是服务端死循环 只要服务器不死 他们就一直在使用
	// 服务端程序停了之后 会释放进程地址空间 也就不存在内存泄漏
	return 0;
}
